package com.bilisummarize.service.impl;

import com.bilisummarize.bean.ResponseType;
import com.bilisummarize.bean.SubtitleObject;
import com.bilisummarize.entity.BiliChatRecord;
import com.bilisummarize.entity.BiliSummarizeUser;
import com.bilisummarize.entity.BiliVideoSummarize;
import com.bilisummarize.repository.BiliChatRecordRepository;
import com.bilisummarize.repository.BiliSummarizeUserRepository;
import com.bilisummarize.repository.BiliVideoSummarizeRepository;
import com.bilisummarize.service.BiliService;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.RequestBody;

import jakarta.servlet.http.HttpServletResponse;

@Service
public class BiliServiceImpl implements BiliService {

    public static Boolean sendErrorReport = false; //捕捉到异常时是否发送错误报告。在正式服务环境下应该开启。

    public static String chat3PublicToken = "Bearer sk-OmW8w8iQSzygiC4EAc1d9aCe23C34eAfA0Ee46DbF8531869"; //chat3接口的token
    public static Integer freeChat3Times = 10; // 用户每天可在本软件上免费对话的次数（不包含总结）8531869"; //chat3接口的token
    public static Integer previousMessageLimit = 3; // 对话功能：最大上下文条数
    public static Integer summaryCountLimit = 3; // 同一个视频反复执行分析，存储的解析数量

    @Autowired
    BiliVideoSummarizeRepository summarizeRepository;
    @Autowired
    BiliSummarizeUserRepository userRepository;
    @Autowired
    BiliChatRecordRepository recordRepository;

    @Override
    public ResponseType getSummarize(String url){
        VideoInfo videoInfo = getVideoInfoFromUrl(url);
        if (videoInfo.success){
            String message = "获取成功";
            List<BiliVideoSummarize> summarizeList = summarizeRepository.findAllByAidAndCid(videoInfo.aid,videoInfo.cid);
            if (summarizeList.isEmpty()) {
                message = "本视频尚无解析";
                return new ResponseType().failure(message);
            }
            BiliVideoSummarize summarize = summarizeList.get(0);
            return new ResponseType().success(summarize,message);
        } else {
            return new ResponseType().failure(videoInfo.message);
        }

    }


    @Override
    public ResponseType getSummarizeWithDetail(Integer aid, Integer cid){
        List<BiliVideoSummarize> summarizeList = summarizeRepository.findAllByAidAndCid(aid,cid);
        String message = "获取成功";
        if (summarizeList.isEmpty()) {
            message = "本视频尚无解析";
            return new ResponseType().failure(message);
        }
        BiliVideoSummarize summarize = summarizeList.get(0);
        return new ResponseType().success(summarize,message);
    }

    @Override
    public ResponseType summarize(String url, String sessdata, HttpServletResponse httpServletResponse){
        VideoInfo videoInfo = getVideoInfoFromUrl(url);
        if (videoInfo.success){
            Integer aid = videoInfo.aid;
            Integer cid = videoInfo.cid;
            String title = videoInfo.title;
//            System.out.println("aid:"+aid);
//            System.out.println("cid:"+cid);

            String message;
            List<BiliVideoSummarize> summarizeList = summarizeRepository.findAllByAidAndCid(videoInfo.aid,videoInfo.cid);
            BiliVideoSummarize biliVideoSummarize;
            if (summarizeList.isEmpty() || summarizeList.size() <= summaryCountLimit) {
//                message = "本视频尚无解析";
                // 视频尚无解析，生成一个。先请求获取字幕Url
                biliVideoSummarize = new BiliVideoSummarize();

                SubtitleResult result = getAISubtitleURL(aid,cid,sessdata);
                String subtitleUrl = result.subtitleUrl;
//                System.out.println("subtitleUrl："+subtitleUrl);
//                System.out.println("message:" + result.message);

                if (subtitleUrl == null) {
                    return new ResponseType().failure("该视频没有AI字幕，无法分析");
                }

                // 通过Url请求字幕
                SubtitleOutput subtitleOutput = getAISubtitleFromURL(subtitleUrl);
                List<SubtitleObject> subtitleObjects = subtitleOutput.subtitleObjects;
                //对原字幕进行一次合并，使一句话内容更长，节省时间戳
                subtitleObjects = combineSubtitle(subtitleObjects);
                String extractedSubtitle = extractSubtitleString(subtitleObjects);

                //使用字幕请求chatGPT
                ChatGPTResponse chatGPTResponse = gptSummarizeWithTimeAndTitle(extractedSubtitle,title,httpServletResponse);
                if (chatGPTResponse.success){
                    //对话完成，将结果插入记录表
                    System.out.println(chatGPTResponse.aiText);
                    biliVideoSummarize.setAid(aid);
                    biliVideoSummarize.setCid(cid);
                    biliVideoSummarize.setAiSubtitle(extractedSubtitle);
                    biliVideoSummarize.setSummarize(chatGPTResponse.aiText);
                    biliVideoSummarize.setTitle(title);
                    biliVideoSummarize.setCreateTime(new Date());
                    summarizeRepository.save(biliVideoSummarize);
                    return new ResponseType().success(biliVideoSummarize,"请求成功");
                }
                return new ResponseType().failure(chatGPTResponse,"请求失败");
            } else {
                biliVideoSummarize = summarizeList.get(0);
                message = "获取成功";
                return new ResponseType().success(biliVideoSummarize,message);
            }
        } else {
            return new ResponseType().failure("未能获取视频信息");
        }

    }

    @Override
    public ResponseType summarizeWithDetail(Integer aid, Integer cid, String subtitleUrl, String title, HttpServletResponse httpServletResponse){
        List<BiliVideoSummarize> biliVideoSummarizeList = summarizeRepository.findAllByAidAndCid(aid,cid);
        if (biliVideoSummarizeList.size() >= summaryCountLimit) {
            //数据库中已有本视频的提纲，且数量足够多，则返回其中一个随机的对象
            // 创建一个 Random 对象
            Random random = new Random();

            // 生成一个随机的索引值，范围在 0 到列表大小减 1 之间
            int randomSeq = random.nextInt(biliVideoSummarizeList.size());
            return new ResponseType().success(biliVideoSummarizeList.get(randomSeq),"获取视频提纲成功");
        } else {
            //数据库中没有提纲，请求字幕并生成一次提纲
            BiliVideoSummarize biliVideoSummarize = new BiliVideoSummarize();

            SubtitleOutput subtitleOutput = getAISubtitleFromURL(subtitleUrl);
            List<SubtitleObject> subtitleObjects = subtitleOutput.subtitleObjects;
            //对原字幕进行一次合并，使一句话内容更长，节省时间戳
            subtitleObjects = combineSubtitle(subtitleObjects);
            String extractedSubtitle = extractSubtitleString(subtitleObjects);

            //使用字幕请求chatGPT
            ChatGPTResponse chatGPTResponse = gptSummarizeWithTimeAndTitle(extractedSubtitle,title, httpServletResponse);
            if (chatGPTResponse.success){
                //对话完成，将结果插入记录表
                biliVideoSummarize.setAid(aid);
                biliVideoSummarize.setCid(cid);
                biliVideoSummarize.setTitle(title);
                biliVideoSummarize.setAiSubtitle(extractedSubtitle);
                biliVideoSummarize.setSummarize(chatGPTResponse.aiText);
                biliVideoSummarize.setCreateTime(new Date());
                biliVideoSummarize.setSequence(biliVideoSummarizeList.size()+1);
                summarizeRepository.save(biliVideoSummarize);
                return new ResponseType().success(biliVideoSummarize,"请求成功");
            }
            return new ResponseType().failure(chatGPTResponse,"请求失败");

        }
    }

    @Override
    public ResponseType chat(String url, String sessdata, String userText, HttpServletResponse httpServletResponse){
        VideoInfo videoInfo = getVideoInfoFromUrl(url);
        if (videoInfo.success){
            Integer aid = videoInfo.aid;
            Integer cid = videoInfo.cid;

            //调用请求字幕的接口，但是这次只关心结果中的用户mid，以此作为用户的ID
            SubtitleResult subtitleResult = getAISubtitleURL(aid, cid, sessdata);
            if (subtitleResult.success && subtitleResult.mid != null){
                Integer userId = subtitleResult.mid;
                BiliSummarizeUser user = initializeOrUpdateUser(userId.toString());
                if (user.getRemainingScore() <= 0){
                    return new ResponseType().failure("用户今日剩余对话次数不足！");
                }
                user.setMid(subtitleResult.mid);
                user.setNickname(subtitleResult.nickname);
                user.setSessdata(sessdata);

                user.setRemainingScore(user.getRemainingScore()-1);
                userRepository.save(user);
                ChatGPTResponse chatGPTResponse = chatWithSummarize(userId.toString(), aid, cid, userText, httpServletResponse);
                if (chatGPTResponse.success){
                    return new ResponseType().success(chatGPTResponse,chatGPTResponse.message);
                } else {
                    return new ResponseType().failure(chatGPTResponse,chatGPTResponse.message);
                }
            } else {
                return new ResponseType().failure("未能从B站获取用户的信息");
            }


        } else {
            return new ResponseType().failure("未能获取视频信息");
        }
    }

    @Override
    public ResponseType chatWithDetail(Integer aid, Integer cid, Integer userId, String userText, HttpServletResponse httpServletResponse){
        BiliSummarizeUser user = initializeOrUpdateUser(userId.toString());
        if (user.getRemainingScore() <= 0){
            return new ResponseType().failure("用户今日剩余对话次数不足！");
        }

        user.setRemainingScore(user.getRemainingScore()-1);
        userRepository.save(user);
        ChatGPTResponse chatGPTResponse = chatWithSummarize(userId.toString(), aid, cid, userText, httpServletResponse);
        if (chatGPTResponse.success){
            return new ResponseType().success(chatGPTResponse,chatGPTResponse.message);
        } else {
            return new ResponseType().failure(chatGPTResponse,chatGPTResponse.message);
        }
    }

    public void sendErrorReport(String type, String message){
        if (sendErrorReport){
            try {
                URL url = new URL("https://t.picknewtab.com/e.gif" +
                        "?t="+type+"&m="+message+"&c=B站视频总结器&v=1.00");
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("GET");

//                BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
//                String inputLine;
//                StringBuilder response = new StringBuilder();
//
//                while ((inputLine = in.readLine()) != null) {
//                    response.append(inputLine);
//                }
//                in.close();
//
//                System.out.println(response.toString());
                connection.disconnect();

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Data
    public class VideoInfo{
        Integer aid;
        Integer cid;
        String message;
        Boolean success;
        String title;
    }

    /**
     * 1. 通过URL解析得到视频的信息
     * 从url提取BVID与分P，请求接口获取aid、cid
     */
    public VideoInfo getVideoInfoFromUrl(String url){
        // 从URL中提取BVID.URL有两种类型，一种是/结尾一种是?结尾。
        int start = url.indexOf("/BV");
        int end = url.indexOf("/", start + 1);
        int questionMarkIndex = url.indexOf("?");
        if (end == -1 || (questionMarkIndex != -1 && questionMarkIndex < end)) {
            end = (questionMarkIndex != -1) ? questionMarkIndex : url.length();
        }
        String bvid = url.substring(start + 1, end);

        String pattern = "p=(\\d+)"; // 匹配p=x的正则表达式

        // 从URL中提取p
        Pattern ptn = Pattern.compile(pattern);
        Integer p = 1;

        Matcher m = ptn.matcher(url);
        if (m.find()) { // 如果有匹配到p=x的内容，则输出x
            p = Integer.valueOf(m.group(1));
        }

        VideoInfo result = new VideoInfo();
        result.success = false;
        try{
            URL urlConnect = new URL("https://api.bilibili.com/x/web-interface/view?bvid=" + bvid);
            HttpURLConnection conn = (HttpURLConnection) urlConnect.openConnection();
            conn.setRequestMethod("GET");

            int responseCode = conn.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String inputLine;
                StringBuilder response = new StringBuilder();

                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();

                // 解析JSON
                JSONObject jsonResponse = new JSONObject(response.toString());
                JSONObject data = jsonResponse.getJSONObject("data");
                JSONArray pages = data.getJSONArray("pages");

                // 获取aid
                Integer aid = data.getInt("aid");


                // 获取cid
                JSONObject page = pages.getJSONObject(p-1);
                Integer cid = page.getInt("cid");

                // 获取title: 如果P=1则直接取大标题，如果P!=1，取大标题+小标题
                String title;
                if (p == 1) {
                    title = data.getString("title");
                } else {
                    title = data.getString("title") + " " + page.getString("part");
                }

                // 封装到结果中
                result.aid = aid;
                result.title = title;
                result.cid = cid;
                result.success = true;
                result.message = "获取成功";

            } else {
                System.out.println("获取视频信息失败，错误码：" + responseCode);
                result.message = "获取视频信息失败！";
            }
        } catch (Exception e){
            e.printStackTrace();
            result.message = "获取视频信息失败！参考信息："+e.getMessage();
            sendErrorReport("接口异常",result.message);
        }
        return result;
    }

    @Data
    public class SubtitleResult{
        String subtitleUrl;
        Integer mid;
        String nickname;
        String message;
        Boolean success;
    }

    /**
     * 2. 通过aid cid sessdata获取字幕接口的URL地址
     * 这个地址顺便也会解析出用户的信息
     */
    public SubtitleResult getAISubtitleURL(Integer aid, Integer cid, String sessdata){
        SubtitleResult result = new SubtitleResult();
        result.success = false;
        try {
            URL url = new URL("https://api.bilibili.com/x/player/v2?aid="+aid+"&cid="+cid);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            String cookie = "SESSDATA="+sessdata;
            conn.addRequestProperty("Cookie", cookie);

            int responseCode = conn.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String inputLine;
                StringBuilder response = new StringBuilder();

                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();

                // 解析JSON
                JSONObject jsonResponse = new JSONObject(response.toString());
                JSONObject data = jsonResponse.getJSONObject("data");

                // 获取用户的ID和昵称
                Integer mid = data.getInt("login_mid");
                String nickname = data.getString("name");

                JSONObject subtitle = data.getJSONObject("subtitle");
                JSONArray subtitles = subtitle.getJSONArray("subtitles");

                JSONObject target = subtitles.getJSONObject(0);
                String subtitleUrl = target.getString("subtitle_url");
                subtitleUrl = "https:"+subtitleUrl;

                result.nickname = nickname;
                result.mid = mid;
                result.subtitleUrl = subtitleUrl;
                result.message = "获取成功";
                result.success = true;

            } else {
                System.out.println("请求字幕信息失败，错误码：" + responseCode);
                result.message = "请求字幕信息失败，错误码：" + responseCode;
            }
        } catch (Exception e) {
            result.message = "请求字幕信息失败，参考信息：" + e.getMessage();
            if (!Objects.equals(e.getMessage(), "JSONArray[0] not found.")) {
                sendErrorReport("接口异常",result.message);
            } else {
                //视频没有字幕是一种常见的情况，该类错误不上报，后面可能会另起一类接口专门处理
//                System.out.println("该视频没有字幕");
            }
        }

        return result;

    }

    @Data
    public class SubtitleOutput{
        String subtitleResult;
        List<SubtitleObject> subtitleObjects;
        String message;
    }

    /**
     * 3.通过2获得的URL请求到字幕的信息，将其组装到一个String
     * 组装成功后返回
     */
    public SubtitleOutput getAISubtitleFromURL(String subtitleUrl){
        SubtitleOutput result = new SubtitleOutput();
        StringBuilder subtitleResult = new StringBuilder();
        try {
            URL url = new URL(subtitleUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");

            int responseCode = conn.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String inputLine;
                StringBuilder response = new StringBuilder();

                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();

                // 解析JSON
                JSONObject jsonResponse = new JSONObject(response.toString());
                JSONArray subtitles = jsonResponse.getJSONArray("body");

                // 定义一个TypeReference来指定目标对象列表类型
                ObjectMapper objectMapper = new ObjectMapper();
                CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(List.class, SubtitleObject.class);

                // 使用ObjectMapper将JSONArray转换为List<SubtitleObject>
                result.subtitleObjects = objectMapper.readValue(subtitles.toString(), listType);

                // 组装subtitles列表内容（如果采用非时间戳，可以用下方直接拼接的结果
//                for (int i = 0; i < subtitles.length(); i++) {
//                    JSONObject subtitleObject = subtitles.getJSONObject(i);
////                    subtitleResult = subtitleResult + subtitleObject.getString("content");
//                    subtitleResult.append(subtitleObject.getString("content"));
//                }
//                result.subtitleResult = subtitleResult.toString();
                result.message = "获取成功";

            } else {
                System.out.println("请求字幕内容失败，错误码：" + responseCode);
                result.message = "请求字幕内容失败，错误码：" + responseCode;
            }
        } catch (Exception e) {
            e.printStackTrace();
            result.message = "请求字幕内容失败，参考信息：" + e.getMessage();
            sendErrorReport("接口异常",result.message);
        }

        return result;
    }


    @Data
    public class ChatGPTResponse{
        String aiText;
        String message;
        Boolean success;
    }

    @Data
    public class PreviousMessage{
        String role; //消息角色 : system 预设； user 用户提问； assistant AI回答
        String content; //消息内容
    }

    /**
     * 4. 根据CHATGPT生成总结
     * 将AI字幕和预设的提示发送给GPT
     * 获取其回复并返回
     */
    public ChatGPTResponse gptSummarize(String subtitles, HttpServletResponse httpServletResponse){
        List<PreviousMessage> previousMessageList = new ArrayList<>();
        PreviousMessage p = new PreviousMessage();
        p.role = "system";
        p.content = "以下是一个视频的AI字幕，请从中总结出视频的要点，并按原行文顺序将其有序罗列。";
        previousMessageList.add(p);
        return sendMessage(subtitles,previousMessageList,httpServletResponse);
    }

    public ChatGPTResponse gptSummarizeWithTime(String subtitles, HttpServletResponse httpServletResponse){
        List<PreviousMessage> previousMessageList = new ArrayList<>();
//        我发现用预设 根本无法达到总结的效果，还是得直接把要求写在字幕文本前面
//        PreviousMessage p = new PreviousMessage();
//        p.role = "system";
//        p.content = "你是一个视频总结助手，用户会将视频的字幕给你分析。";
//        previousMessageList.add(p);

        subtitles = "以下是一个视频的AI字幕以及其时间，请从中合并并总结视频内容，你应当将字幕总结为2~5条要点。请严格按照“时间+内容”格式回答。格式示范：0:00 要点内容, 1:30 要点内容...。以下是需要总结的文本：" + subtitles;

        ChatGPTResponse chatGPTResponse = sendMessage(subtitles,previousMessageList,httpServletResponse);
        return chatGPTResponse;
    }

    public ChatGPTResponse gptSummarizeWithTimeAndTitle(String subtitles, String title, HttpServletResponse httpServletResponse){
//        System.out.println(title);
        if (title==null) {
            return gptSummarizeWithTime(subtitles,httpServletResponse);
        }
        List<PreviousMessage> previousMessageList = new ArrayList<>();
//        PreviousMessage p = new PreviousMessage();
//        p.role = "system";
//        p.content = "你是一个视频总结助手，用户会将视频的字幕给你分析和提取关键点。";
//        previousMessageList.add(p);


        String subtitlesFinal = "以下是名为 “"+title+"” 的视频的AI字幕以及其时间，请从中合并并总结视频内容，你应当将字幕总结为2~5条要点，形成提纲。请严格按照“时间+内容”格式回答。格式示范：0:00 要点内容, 1:30 要点内容...。以下是需要总结的文本：" + subtitles;
//        System.out.println(subtitles);
        ChatGPTResponse chatGPTResponse = sendMessage(subtitlesFinal,previousMessageList,httpServletResponse);
        return chatGPTResponse;
    }

    public class RequestBody{
        private List<PreviousMessage> messages;
        private boolean stream;
        private String model;
        private double temperature;
        private double presence_penalty;
        private double frequency_penalty;
        private int top_p;

        public RequestBody(List<PreviousMessage> messages, boolean stream, String model, double temperature, double presence_penalty, double frequency_penalty, int top_p) {
            this.messages = messages;
            this.stream = stream;
            this.model = model;
            this.temperature = temperature;
            this.presence_penalty = presence_penalty;
            this.frequency_penalty = frequency_penalty;
            this.top_p = top_p;
        }
    }


    /**
     * CHATGPT 发送消息
     */
    public ChatGPTResponse sendMessage(String userText, List<PreviousMessage> previousMessageList,
                                       HttpServletResponse response){
        ChatGPTResponse result = new ChatGPTResponse();
        result.success = false;

//        System.out.println(userText);

        if (previousMessageList == null) {
            previousMessageList = new ArrayList<PreviousMessage>();
        }

        PreviousMessage question = new PreviousMessage();
        question.content = userText;
        question.role = "user";
        previousMessageList.add(question);

        try {
            // 输出的信息流初始化
            OutputStream out = null;
            if (response != null) {
                response.setContentType("text/event-stream");
                response.setHeader("Cache-Control", "no-cache");
                response.setHeader("Connection", "keep-alive");
                out = response.getOutputStream();
            }

            // 请求对话接口
            URL url = new URL("https://api.opchatai.site/v1/chat/completions");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
            connection.setRequestProperty("Authorization", chat3PublicToken);
            connection.setDoOutput(true);

            RequestBody requestBody = new RequestBody(
                    previousMessageList,
                    true,
                    "deepseek-chat",
                    0.5,
                    0.0,
                    0.0,
                    1
            );

            String jsonInputString = new Gson().toJson(requestBody);

            OutputStream outputStream = connection.getOutputStream();
            outputStream.write(jsonInputString.getBytes(StandardCharsets.UTF_8));
            outputStream.flush();

            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                InputStream inputStream = connection.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                String line;
                String responseContent = "";
                while ((line = reader.readLine()) != null) {
                    if (!line.isEmpty()) {
                        // 去掉每行开头的"data:"
                        String jsonString = line.replaceFirst("data:", "");

                        if (jsonString.trim().equals("[DONE]")) {
                            // 对话完成，将最终结果返回
                            result.aiText = responseContent;
                            result.message = "对话完成";
                            result.success = true;

                            if (response != null){
                                String successOutput = "data:{" +
                                        "\"success\":true," +
                                        "\"message\":\"GPT对话完成\"," +
                                        "\"data\":{" +
                                        "\"aiText\":" + "\"" + responseContent.replace("\n", "\\r\\n") + "\"" +
                                        "}" +
                                        "}";
//                                System.out.println(successOutput);
                                out.write((successOutput + "\n\n").getBytes());
                                out.flush();
                            }
                        } else {
                            // 将每行JSON数据解析为JsonObject
                            JsonObject jsonObject = JsonParser.parseString(jsonString).getAsJsonObject();
                            // 检查是否存在"choices"数组和第一个元素的"delta"对象
                            JsonArray choices = jsonObject.getAsJsonArray("choices");
                            if (choices != null && choices.size() > 0) {
                                JsonObject delta = choices.get(0).getAsJsonObject().get("delta").getAsJsonObject();
                                if (delta != null && delta.isJsonObject()) {
                                    String content = delta.get("content") != null ? delta.get("content").getAsString() : "";
                                    responseContent += content;
                                }
                            }
                        }

                        if (response != null){
//                            System.out.println(line);
                            out.write((line + "\n\n").getBytes());
                            out.flush();
                        }
                    }
                }

                reader.close();
                inputStream.close();
            } else {
                System.out.println("请求失败: " + connection.getResponseCode());
            }



        } catch (Exception e) {
            e.printStackTrace();
            result.message = "CHATGPT对话失败，参考原因+"+e.getMessage();
            sendErrorReport("接口异常",result.message);
        }
        return result;
    }

    /**
     * 5. 在视频的基础上进行会话
     * 根据视频ID与用户信息，提取上下文
     * 将AI总结的视频内容作为上文
     */
    public ChatGPTResponse chatWithSummarize(String userId, Integer aid, Integer cid, String userText, HttpServletResponse httpServletResponse){
        ChatGPTResponse result = new ChatGPTResponse();
        List<PreviousMessage> previousMessageList = new ArrayList<>();
        PreviousMessage p = new PreviousMessage();

        List<BiliVideoSummarize> vsList = summarizeRepository.findAllByAidAndCid(aid,cid);
        if (vsList.isEmpty()) {
            result.message = "对话失败，未找到总结";
            return result;
        }
        BiliVideoSummarize vs = vsList.get(0);
        p.role = "assistant";
        p.content = vs.getSummarize();
        previousMessageList.add(p);

        List<BiliChatRecord> chatRecordList = recordRepository.findAllByAidAndCidAndUserIdOrderByCreateTime(aid,cid,userId);
        List<BiliChatRecord> subList;
        int size = chatRecordList.size();

        // 限制上下文条数
        if (size > previousMessageLimit) {
            subList = chatRecordList.subList(size - previousMessageLimit, size);
        } else {
            subList = chatRecordList;
        }

        for (int i = 0; i < subList.size(); i++){
            p = new PreviousMessage();
            p.role = "user";
            p.content = chatRecordList.get(i).getUserText();
            previousMessageList.add(p);

            p = new PreviousMessage();
            p.role = "assistant";
            p.content = chatRecordList.get(i).getAiText();
            previousMessageList.add(p);
        }

        result = sendMessage(userText,previousMessageList,httpServletResponse);
        if (result.success){
            // 如果对话成功，则将本对话存入数据库
            BiliChatRecord record = new BiliChatRecord();
            record.setAid(aid);
            record.setCid(cid);
            record.setUserId(userId);
            record.setUserText(userText);
            record.setAiText(result.aiText);
            record.setCreateTime(new Date());
            recordRepository.save(record);
        }

        return result;
    }

    /**
     * 字幕整合（辅助步骤）
     * 将字幕文件多条合为一条，以防字幕过于琐碎，时间戳占比太多
     */
    public List<SubtitleObject> combineSubtitle(List<SubtitleObject> input){
        if (input == null) {
            return null;
        }

        int sectionLength = 100; // 每一个区间的长度（近似值）

        List<SubtitleObject> result = new ArrayList<>();
        int currentLength = 0;
        SubtitleObject current = new SubtitleObject();
        current.setFrom(0);
        current.setContent("");

        for (int i = 0; i<input.size(); i++){
            if (current.getContent().length() < sectionLength) {
                // 长度还未超出上限，追加到本内容末
                current.setContent(current.getContent() + " " + input.get(i).getContent());
                current.setTo(input.get(i).getTo());
                currentLength += input.get(i).getContent().length();

            } else {
                // 长度超出上限，将当前内容追加到结果列表中，并初始化当前对象
                result.add(current);
                current = new SubtitleObject();
                current.setContent(input.get(i).getContent());
                current.setFrom(input.get(i).getFrom());
                current.setTo(input.get(i).getTo());
                currentLength = input.get(i).getContent().length();
            }

        }

        result.add(current);
        return result;
    }

    /**
     * 字幕输出（辅助步骤）
     * 将字幕数组变成一个String输出
     */
    public String extractSubtitleString(List<SubtitleObject> subtitleObjects){
        String result = "";
        for (SubtitleObject subtitleObject : subtitleObjects){
            result = result + formatTime(subtitleObject.getFrom())
                    + " " + subtitleObject.getContent() + " ";
        }
        return result;
    }

    /**
     * 时间格式化（辅助步骤）
     * 将字幕文件的时间（秒）转换为视频所用的分钟格式：
     * 例子：原: 223.9 (秒) -> 3:44 (3分44秒)
     */
    public String formatTime(Number time){
        String result = "";

        Integer seconds = time.intValue();
        Integer minutes = seconds / 60;
        Integer remainingSeconds = seconds % 60;

        result = minutes + ":" + String.format("%02d", remainingSeconds);

        return result;
    }

    /**
     * 初始化/更新用户
     * 给出一个唯一ID，如果没有该用户，则创建一个新的；
     * 如果有，则看看该用户上次刷新额度的时间，如果不是今天，则重置后返回
     * 每次调用用户时都从这里获取
     */
    public BiliSummarizeUser initializeOrUpdateUser(String userId){
        BiliSummarizeUser user = userRepository.findBiliSummarizeUserByUserId(userId);
        if (user == null) {
            user = new BiliSummarizeUser();
            user.setUserId(userId);
            user.setRemainingScore(freeChat3Times);
            user.setLastUseDate(new Date());
            userRepository.save(user);

            return user;
        } else {
            Calendar cal1 = Calendar.getInstance();
            cal1.setTime(user.getLastUseDate());
            Calendar cal2 = Calendar.getInstance();
            cal2.setTime(new Date());

            if (cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
                    cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH) &&
                    cal1.get(Calendar.DAY_OF_MONTH) == cal2.get(Calendar.DAY_OF_MONTH)) {
                return user;
            } else {
                user.setRemainingScore(freeChat3Times);
                user.setLastUseDate(new Date());
                userRepository.save(user);
                return user;
            }
        }
    }

    public ResponseType getUserScore(Integer userId){
        BiliSummarizeUser user = initializeOrUpdateUser(userId.toString());
        return new ResponseType().success(user,"获取信息成功");
    }


}
